package snailAI.Service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingRequest;
import org.springframework.ai.embedding.EmbeddingResponse;
import org.springframework.ai.reader.markdown.config.MarkdownDocumentReaderConfig;
import org.springframework.ai.reader.pdf.ParagraphPdfDocumentReader;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.reader.markdown.MarkdownDocumentReader;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.ai.vectorstore.elasticsearch.ElasticsearchVectorStore;
import org.springframework.ai.zhipuai.ZhiPuAiEmbeddingModel;
import org.springframework.ai.zhipuai.ZhiPuAiEmbeddingOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class HandleFileService {

    /**
     * 文件上传基础路径（可配置）
     */
    private final String basePath
            =
            "D:\\everyDayLearning\\daysInSnail\\garbage\\garbagef1\\";

    private static final int MAX_CHARS_PER_DOC = 3000;//每页最大字符量。

    @Autowired
    ElasticsearchVectorStore elasticsearchVectorStore;
    @Autowired
    ZhiPuAiEmbeddingModel zhiPuAiEmbeddingModel;

    public void uploadFiles(MultipartFile file) {

        // 确保目录存在
        File baseDir = new File(basePath);
        if (!baseDir.exists()) {
            baseDir.mkdirs();
        }

        String originalName = file.getOriginalFilename();
        if (StrUtil.isBlank(originalName)) {
           return;
        }

        File dest = new File(baseDir, originalName);
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            throw new RuntimeException("❌ 文件上传失败：" + originalName, e);
        }
    }


    @Tool(description = "当用户给出文件列表时(关键词：附件名为：)，调用这个分析文件，并且给出总结")
    public String handleFiles
            (@ToolParam(description = "用户查询的文件名字集合")
                                  String... fileNames) {
        StringBuilder totalResult = new StringBuilder();

        for (String name : fileNames) {
            File file = new File(basePath, name);
            if (!file.exists()) {
                totalResult.append("这个文件不存在：").append(name).append("\n");
                continue;

            }
            String ext = FileUtil.extName(file);
            List<Document> docs = parseByType(file, ext);
            totalResult.append("【").append(name).append("】内容：\n");
            for (Document doc : docs) {
                totalResult.append(doc.getText()).append("\n\n");
            }
        }
        return totalResult.toString();
    }
    @Tool(description = "当用户想要让我们记住以上的文件时，调用这个(关键字：附件如下)：")
    public String rememberFiles(
            @ToolParam(description = "用户给出的文件名字集合,当用户消息中含有附件如下时，后面跟着的就是文件名")
            String... fileNames) {
        StringBuilder result = new StringBuilder();
        for (String name : fileNames) {
            File file = new File(basePath, name);
            System.out.println(name);
            // 核心新增：判断文件是否存在
            if (!file.exists()) {
                result.append("❌ 文件不存在，跳过存储：").append(name).append("\n");
                continue;
            }
            // 文件存在则正常解析和存储
            String ext = FileUtil.extName(file);
            List<Document> docs = parseByType(file, ext);
            elasticsearchVectorStore.add(docs);
            result.append("✅ 已成功存储文件：").append(name).append("\n");
        }
        return result.toString().isEmpty() ? "礼貌回答：未接收到有效文件" : result.toString();
    }


    /**
     * 根据文件类型自动选择合适的 Reader
     */
    private List<Document> parseByType(File file, String ext) {
        try {
            List<Document> result = new ArrayList<>();
            String fullContent = null;

            // 1. 解析文件获取完整内容
            if (StrUtil.equalsAnyIgnoreCase(ext, "pdf")) {
                fullContent = String.join("\n",
                        new ParagraphPdfDocumentReader(new FileSystemResource(file)).get().stream()
                                .map(Document::getText)
                                .collect(Collectors.toList())
                );
            } else if (StrUtil.equalsAnyIgnoreCase(ext, "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm")) {
                fullContent = String.join("\n",
                        new TikaDocumentReader(new FileSystemResource(file)).get().stream()
                                .map(Document::getText)
                                .collect(Collectors.toList())
                );
            } else if (StrUtil.equalsAnyIgnoreCase(ext, "md", "markdown")) {
                fullContent = String.join("\n",
                        new MarkdownDocumentReader(new FileSystemResource(file), MarkdownDocumentReaderConfig.defaultConfig()).get().stream()
                                .map(Document::getText)
                                .collect(Collectors.toList())
                );
            } else if (StrUtil.equalsAnyIgnoreCase(ext, "txt", "csv", "json")) {
                fullContent = FileUtil.readUtf8String(file);
            } else {
                return List.of(new Document("这个文件不支持" + ext));
            }

            // 2. 处理空内容情况
            if (StrUtil.isBlank(fullContent)) {
                return List.of(new Document("文件内容为空"));
            }

            // 3. 按静态变量指定的长度拆分内容为多个Document
            int start = 0;
            int contentLength = fullContent.length();
            while (start < contentLength) {
                int end = Math.min(start + MAX_CHARS_PER_DOC, contentLength);
                // 优化：避免在单词中间拆分（可选）
                if (end < contentLength && !Character.isWhitespace(fullContent.charAt(end))) {
                    int lastSpace = fullContent.lastIndexOf(' ', end);
                    if (lastSpace > start) {
                        end = lastSpace;
                    }
                }
                result.add(new Document(fullContent.substring(start, end)));
                start = end;
            }

            return result;

        } catch (Exception e) {
            return List.of(new Document("这个文件解析失败：" + e.getMessage()));
        }
    }
}
